home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK2.toast / Development Kits (Disc 2) / QuickTime / Sample Code / QT Image Transcoders / Transcoder Test App / transcoder.c next >
Encoding:
C/C++ Source or Header  |  1997-02-26  |  16.1 KB  |  609 lines  |  [TEXT/CWIE]

  1. #include <Fonts.h>
  2. #include <LowMem.h>
  3. #include <NumberFormatting.h>
  4. #include <Processes.h>
  5.  
  6. #include <Movies.h>
  7.  
  8. Boolean getMovieFile(FSSpec *theFile);
  9.  
  10. OSErr OpenSelection(FSSpecPtr theDocToOpen);
  11.  
  12. Boolean fPeriodic( TimeValue srcMovieDuration, TimeValue timeNow, StringPtr fileName, StringPtr srcCompression, StringPtr dstCompression);
  13. void fPStrCopy( Str255 s1, Str255 s2 );
  14. void fPStrConcat( Str255 s1, Str255 s2 );
  15. void fSetRGBColor( RGBColor *theColor, short r, short g, short b );
  16. void fPNumToString( float theNum, Str255 theString, short fix );
  17.  
  18. void main(void)
  19. {
  20.     OSErr err;
  21.     FSSpec file;
  22.     Movie sourceMovie;
  23.     short resFref;
  24.     WindowPtr w;
  25.     Rect bounds;
  26.     ImageDescriptionHandle srcDesc = (ImageDescriptionHandle)NewHandle(0);
  27.     ImageDescriptionHandle dstDesc = (ImageDescriptionHandle)NewHandle(0);
  28.     Track srcVideoTrack, dstVideoTrack;
  29.     Media srcVideoMedia, dstVideoMedia;
  30.     Handle nextSample = NewHandle(0);
  31.     Handle srcSample = NewHandle(0);
  32.     long nextSampleSize, srcSampleSize;
  33.     Movie dstMovie = nil;
  34.     short dstResRef = -1;
  35.     TimeValue timeNow = 0;
  36.     TimeValue mediaTime;
  37.     TimeValue sampleDuration;
  38.     Handle dataRef = nil;
  39.     OSType dataRefType;
  40.     ImageTranscodeSequence its;
  41.     short outputFref = 0;
  42.     long fileOffset;
  43.     TimeValue srcMovieDuration;
  44.     Str31 srcCompression;
  45.     FSSpec newFile;
  46.  
  47.     InitGraf(&qd.thePort);
  48.     InitFonts();
  49.     InitWindows();
  50.     InitMenus();
  51.     TEInit();
  52.     InitDialogs(0L);
  53.     InitCursor();
  54.     MaxApplZone();
  55.  
  56.     EnterMovies();
  57.  
  58.     if (!getMovieFile(&file))
  59.         return;
  60.  
  61.     SetRect(&bounds, 75, 75, 75+160,75+120);
  62.     w = NewCWindow(nil, &bounds, file.name, false, 0, (WindowPtr)-1,
  63.         true, 0);
  64.     if (!w) return;
  65.  
  66.     SetPort(w);
  67.  
  68.     err = OpenMovieFile(&file, &resFref, fsRdPerm);
  69.     if (err) return;
  70.  
  71.     err = NewMovieFromFile(&sourceMovie, resFref, nil, (StringPtr)nil,
  72.                 newMovieActive, nil);
  73.     if (err) return;
  74.  
  75.     CloseMovieFile(resFref);
  76.  
  77.     srcVideoTrack = GetMovieIndTrackType(sourceMovie, 1, VideoMediaType, movieTrackMediaType);
  78.     if (!srcVideoTrack) return;
  79.  
  80.     newFile = file;
  81.     newFile.name[++newFile.name[0]] = '!';
  82.     err = CreateMovieFile(&newFile, 'TVOD', -1, createMovieFileDeleteCurFile, &dstResRef, &dstMovie);
  83.     if (err) return;
  84.  
  85.     GetMovieDefaultDataRef(dstMovie, &dataRef, &dataRefType);
  86.  
  87.     err = AddEmptyTrackToMovie(srcVideoTrack, dstMovie, dataRef, dataRefType, &dstVideoTrack);
  88.     if (err) return;
  89.  
  90.     DisposeHandle(dataRef);
  91.  
  92.     err = FSpOpenDF(&newFile, fsRdWrPerm, &outputFref);
  93.     if (err) Debugger();
  94.  
  95.     err = SetFPos(outputFref, fsFromLEOF, 0);
  96.     if (err) Debugger();
  97.  
  98.     err = GetEOF(outputFref, &fileOffset);
  99.     if (err) Debugger();
  100.  
  101.     dstVideoMedia = GetTrackMedia(dstVideoTrack);
  102.     srcVideoMedia = GetTrackMedia(srcVideoTrack);
  103.     GetMediaSampleDescription(srcVideoMedia, 1, (SampleDescriptionHandle)srcDesc);
  104.  
  105.     BlockMoveData((**srcDesc).name, srcCompression, 32);
  106.  
  107.     err = ImageTranscodeSequenceBegin(&its, srcDesc, 'mjpb', &dstDesc);
  108.     if (err) Debugger();
  109.  
  110.     srcMovieDuration = GetMovieDuration(sourceMovie);
  111.  
  112.     while (!fPeriodic(srcMovieDuration, timeNow, file.name, srcCompression, (StringPtr)"\pMotion JPEG Format B")) {
  113.         TimeValue mediaTime = TrackTimeToMediaTime(timeNow, srcVideoTrack);
  114.         void *dstData;
  115.         long dstDataSize;
  116.  
  117.         err = GetMediaSample(srcVideoMedia, srcSample, 0, &srcSampleSize, mediaTime, nil, &sampleDuration,
  118.                     (SampleDescriptionHandle)srcDesc, nil, 1, nil, nil);
  119.         if (err) Debugger();
  120.  
  121.         HLock(srcSample);
  122.         err = ImageTranscodeFrame(its, *srcSample, srcSampleSize, &dstData, &dstDataSize);
  123.         if (err) Debugger();
  124.  
  125.         HUnlock(srcSample);
  126.  
  127.         err = FSWrite(outputFref, &dstDataSize, dstData);
  128.         if (err) Debugger();
  129.  
  130.         ImageTranscodeDisposeFrameData(its, dstData);
  131.  
  132.         err = AddMediaSampleReference(dstVideoMedia, fileOffset, dstDataSize, sampleDuration, (SampleDescriptionHandle)dstDesc, 1, 0, nil);
  133.         if (err) Debugger();
  134.  
  135.         fileOffset += dstDataSize;
  136.  
  137.         GetTrackNextInterestingTime(srcVideoTrack, nextTimeMediaSample, timeNow, 1, &timeNow, nil);
  138.         if (timeNow == -1)
  139.             break;
  140.     }
  141.  
  142.     FSClose(outputFref);
  143.     outputFref = 0;
  144.  
  145.     err = InsertMediaIntoTrack(dstVideoTrack, 0, 0, GetMediaDuration(dstVideoMedia), 0x010000);
  146.     if (err) Debugger();
  147.  
  148.     AddMovieResource(dstMovie, dstResRef, nil, nil);
  149.     CloseMovieFile(dstResRef);
  150.  
  151.     ImageTranscodeSequenceEnd(its);
  152.     DisposeMovie(sourceMovie);
  153.     DisposeMovie(dstMovie);
  154.     DisposeHandle(nextSample);
  155.     DisposeHandle((Handle)srcDesc);
  156.     DisposeHandle((Handle)dstDesc);
  157.  
  158.     OpenSelection(&newFile);
  159. }
  160.  
  161.  
  162. /*==================================================================================*/
  163. Boolean fPeriodic( TimeValue srcMovieDuration, TimeValue timeNow, StringPtr fileName, StringPtr srcCompression, StringPtr dstCompression) {
  164. /* Check for events, update progress bar. Return true to quit program.                */
  165.  
  166.     #define kTimeStamps 10
  167.  
  168.     long i;
  169.     Boolean quit;
  170.     EventRecord theEvent;
  171.     RGBColor theColor;
  172.     float framesPerSecond;
  173.     long startTick;
  174.     long endTick;
  175.     Str255 theString;
  176.     WindowRef aWindow;
  177.     static gSetup;
  178.     static Rect gTheRect;
  179.     static Rect gTextRect;
  180.     static Rect gFileRect;
  181.     static Rect gSrcCompressionRect, gDstCompressionRect;
  182.     static Rect gFillRect;
  183.     static long gTimeStamps[kTimeStamps];
  184.     static long gNextStamp;
  185.     static WindowPtr gWindow = nil;
  186.  
  187.     quit = false;
  188.  
  189.     /* Check for events */
  190.     if( OSEventAvail( mDownMask | keyDownMask, &theEvent) ) {
  191.         GetNextEvent(mDownMask | keyDownMask, &theEvent);
  192.         switch( theEvent.what ) {
  193.             case mouseDown:
  194.                 if (FindWindow( theEvent.where, &aWindow ) == inGoAway) {
  195.                     if (TrackGoAway(aWindow, theEvent.where))
  196.                         quit = true;
  197.                 }
  198.                 break;
  199.             case keyDown:
  200.                 if( theEvent.modifiers & cmdKey )
  201.                     if( (char)theEvent.message == 'Q' ||
  202.                         (char)theEvent.message == 'q' ||
  203.                         (char)theEvent.message == '.' )
  204.                         quit = true;
  205.                 break;
  206.             }
  207.         }
  208.  
  209.     /* Draw progress the first time */
  210.     if( !gSetup ) {
  211.         gWindow = GetNewCWindow(128, nil, (WindowPtr)-1);
  212.         SetPort(gWindow);
  213.  
  214.         gTheRect = gWindow->portRect;
  215.         gTheRect.left += 20;
  216.         gTheRect.bottom -= 20;
  217.         gTheRect.top = gTheRect.bottom - 20;
  218.         gTheRect.right -= 80;
  219.         gTextRect = gTheRect;
  220.         OffsetRect( &gTextRect, 0, -40 );
  221.         gFileRect = gTheRect;
  222.         OffsetRect( &gFileRect, 0, -100 );
  223.         gSrcCompressionRect = gTheRect;
  224.         OffsetRect( &gSrcCompressionRect, 0, -80 );
  225.         gDstCompressionRect = gTheRect;
  226.         OffsetRect( &gDstCompressionRect, 0, -60 );
  227.         FrameRect( &gTheRect );
  228.         InsetRect( &gTheRect, 1, 1 );
  229.         gFillRect = gTheRect;
  230.         if( gWindow->portBits.rowBytes < 0 )
  231.             if( (*((CGrafPtr)gWindow)->portPixMap)->pixelSize > 1 ) {
  232.                 fSetRGBColor( &theColor, 205, 205, 255 );
  233.                 RGBForeColor( &theColor );
  234.                 PaintRect( &gFillRect );
  235.                 fSetRGBColor( &theColor, 0, 0, 0 );
  236.                 RGBForeColor( &theColor );
  237.                 }
  238.  
  239.         for( i = 0; i < kTimeStamps; i++ )
  240.             gTimeStamps[i] = -1;
  241.         gNextStamp = 0;
  242.  
  243.         MoveTo( gTextRect.left, gTextRect.bottom );
  244.         DrawString( "\pFrames per second: " );
  245.         gTextRect.left += StringWidth( "\pFrames per second: " );
  246.  
  247.         MoveTo( gFileRect.left, gFileRect.bottom );
  248.         DrawString( "\pSource file: " );
  249.         TextFace(bold);
  250.         DrawString( fileName );
  251.         TextFace(normal);
  252.  
  253.         MoveTo( gSrcCompressionRect.left, gSrcCompressionRect.bottom );
  254.         DrawString( "\pOriginal format: " );
  255.         TextFace(bold);
  256.         DrawString( srcCompression );
  257.         TextFace(normal);
  258.  
  259.         MoveTo( gDstCompressionRect.left, gDstCompressionRect.bottom );
  260.         DrawString( "\pTarget format: " );
  261.         TextFace(bold);
  262.         DrawString( dstCompression );
  263.         TextFace(normal);
  264.  
  265.         gSetup = true;
  266.         }
  267.  
  268.     /* Update progress the rest of the time */
  269.     else {
  270.  
  271.         gFillRect.right = gTheRect.left + (gTheRect.right - gTheRect.left) *
  272.             timeNow / (float)srcMovieDuration;
  273.         fSetRGBColor( &theColor, 86, 86, 86 );
  274.         RGBForeColor( &theColor );
  275.         PaintRect( &gFillRect );
  276.         fSetRGBColor( &theColor, 0, 0, 0 );
  277.         RGBForeColor( &theColor );
  278.         TextMode(srcCopy);
  279.  
  280.         startTick = gTimeStamps[gNextStamp];
  281.         endTick = TickCount();
  282.         gTimeStamps[gNextStamp++] = endTick;
  283.         if( gNextStamp == kTimeStamps )
  284.             gNextStamp = 0;
  285.         if( startTick != -1 ) {
  286.             framesPerSecond = kTimeStamps / (float)(endTick - startTick) * 60.0;
  287.             fPNumToString( framesPerSecond, theString, 2 );
  288.             MoveTo( gTextRect.left, gTextRect.bottom );
  289.             TextFace(bold);
  290.             DrawString( theString );
  291.             DrawString( "\p      " );
  292.             }
  293.         }
  294.  
  295.     return( quit );
  296.     }
  297.  
  298. /*==================================================================================*/
  299. void fSetRGBColor( RGBColor *theColor, short r, short g, short b ) {
  300.  
  301.     theColor->red = r * 256;
  302.     theColor->green = g * 256;
  303.     theColor->blue = b * 256;
  304.     }
  305.  
  306. /*==================================================================================*/
  307. void fPNumToString( float theNum, Str255 theString, short fix ) {
  308.  
  309.     short i;
  310.     Boolean negative;
  311.     long wholeNum;
  312.     float fraction;
  313.     long fractNum;
  314.     Str255 fractString;
  315.     short padCount;
  316.  
  317.     negative = false;
  318.     if( theNum < 0 ) {
  319.         negative = true;
  320.         theNum = -theNum;
  321.         }
  322.  
  323.     /* Round the number off before proceeding */
  324.     fraction = 0.500001;
  325.     for( i = 0; i < fix; i++ )
  326.         fraction /= 10;
  327.     theNum += fraction;
  328.  
  329.     /* Set up whole number portion of the string */
  330.     wholeNum = theNum;
  331.  
  332.     /* Set up fractional portion of string */
  333.     fraction = theNum - wholeNum;
  334.     for( i = 0; i < fix; i++ )
  335.         fraction *= 10;
  336.     fractNum = fraction;
  337.  
  338.     /* Build the string */
  339.     NumToString( wholeNum, theString );
  340.     theString[++theString[0]] = '.';
  341.     NumToString( fractNum, fractString );
  342.     padCount = fix - fractString[0];
  343.     for( i = 0; i < padCount; i++ )
  344.         theString[++theString[0]] = '0';
  345.     fPStrConcat( theString, fractString );
  346.  
  347.     /* Strip trailing zero's (except the one after the decimal place if any) */
  348.     while( theString[theString[0]] == '0' &&
  349.         theString[theString[0] - 1] != '.' &&
  350.         theString[0] > 3 )
  351.         theString[0]--;
  352.  
  353.     if( negative ) {
  354.         BlockMove( &theString[1], &theString[2], theString[0] );
  355.         theString[1] = '-';
  356.         theString[0]++;
  357.         }
  358.     }
  359.  
  360. /*==================================================================================*/
  361. void fPStrCopy( Str255 s1, Str255 s2 ) {
  362. /* Copies pascal string s2 into s1 (bowing to strcpy() parameter ordering).            */
  363.  
  364.     BlockMove( s2, s1, 255 < s2[0] + 1 ? 255 : s2[0] + 1 );
  365.     }
  366.  
  367. /*==================================================================================*/
  368. void fPStrConcat( Str255 s1, Str255 s2 ) {
  369. /* Attaches pascal string s2 to pascal string s1.                                    */
  370.  
  371.     short i;
  372.  
  373.     i = 255 - s1[0] < s2[0] ? 255 - s1[0] : s2[0];
  374.     BlockMove( &s2[1], &s1[s1[0] + 1], i );
  375.     s1[0] += i;
  376.     }
  377.  
  378. /*==================================================================================*/
  379.  
  380. pascal OSErr AEOpenDoc(AppleEvent *message, AppleEvent *reply,long refCon);
  381. OSErr MissedAEParameters (AppleEvent *message);
  382.  
  383. Boolean getMovieFile(FSSpec *theFile)
  384. {
  385.     Boolean result = false;
  386.     unsigned long gStartTicks = LMGetTicks();
  387.     void *upp = NewAEEventHandlerProc(AEOpenDoc);
  388.  
  389.     theFile->vRefNum = 0;
  390.  
  391.     AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, upp, (long)theFile, false);
  392.  
  393.     while (gStartTicks + 30 > (unsigned long)LMGetTicks()) {
  394.         EventRecord event;
  395.  
  396.         WaitNextEvent(everyEvent, &event, 0, 0);
  397.         if (event.what == kHighLevelEvent)
  398.             AEProcessAppleEvent(&event);
  399.     }
  400.  
  401.     AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, upp, false);
  402.  
  403.  
  404.     if (theFile->vRefNum == 0) {
  405.         StandardFileReply reply;
  406.         SFTypeList types;
  407.  
  408.         types[0] = MovieFileType;
  409.         StandardGetFilePreview(nil, 1, types, &reply);
  410.  
  411.         result = reply.sfGood;
  412.         if (result)
  413.             *theFile = reply.sfFile;
  414.     }
  415.     else
  416.         result = true;
  417.  
  418.     return result;
  419. }
  420.  
  421. pascal OSErr AEOpenDoc(AppleEvent *message, AppleEvent *reply,long refCon)
  422. {
  423.     FSSpec fss;
  424.     AEDescList docList;
  425.     long index, itemsInList;
  426.     Size actualSize;
  427.     AEKeyword keywd;
  428.     DescType typeCode;
  429.     OSErr err;
  430.     FSSpec *filePtr = (FSSpec *)refCon;
  431.  
  432.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  433.     if(err) goto bail;
  434.  
  435.     err = MissedAEParameters(message);
  436.     if(err) goto bail;
  437.  
  438.     err = AECountItems(&docList, &itemsInList);
  439.     if(err) goto bail;
  440.  
  441.     for (index = 1; index <= itemsInList; index++) {
  442.         HFileInfo pb;
  443.  
  444.         err = AEGetNthPtr(&docList, index, typeFSS, &keywd, &typeCode,
  445.                     (Ptr)&fss, sizeof(FSSpec), &actualSize);
  446.         if(err) goto bail;
  447.  
  448.         // need to figure out if this is a directory or a file
  449.  
  450.         pb.ioVRefNum = fss.vRefNum;
  451.         pb.ioFDirIndex = 0;
  452.         pb.ioDirID = fss.parID;
  453.         pb.ioNamePtr = fss.name;
  454.         err = PBGetCatInfoSync((void *)&pb);
  455.         if (!err) {
  456.             if (pb.ioFlAttrib & 16) {
  457.                 fss.parID = pb.ioDirID;
  458.             }
  459.             else {
  460.                 *filePtr = fss;
  461.                 break;
  462.             }
  463.         }
  464.     }
  465.  
  466.     err = AEDisposeDesc(&docList);
  467.  
  468. bail:
  469.     return err;
  470. }
  471.  
  472. OSErr MissedAEParameters (AppleEvent *message)
  473.     {
  474.     DescType typeCode;
  475.     Size actualSize;
  476.     OSErr err;
  477.  
  478.     err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  479.             &typeCode, nil, 0L, &actualSize);
  480.     if (err == errAEDescNotFound)
  481.         return(noErr);
  482.     return(err = noErr ? errAEEventNotHandled : err);
  483.     }
  484.  
  485.  
  486. OSErr FindAProcess(OSType typeToFind, OSType creatorToFind, ProcessSerialNumberPtr processSN);
  487.  
  488. /* OpenSelection takes a FSSpec pointer, and creates a Finder Open Selection */
  489. /* AppleEvent for the document described by the FSSpec.  This can be an */
  490. /* application or document. */
  491. OSErr OpenSelection(FSSpecPtr theDocToOpen)
  492. {
  493.     OSErr err;
  494.     AppleEvent aeEvent;
  495.     AEDesc myAddressDesc, aeDirDesc, listElem;
  496.     FSSpec dirSpec;
  497.     AEDesc fileList;
  498.     ProcessSerialNumber process;
  499.     AliasHandle DirAlias = nil, FileAlias = nil;
  500.  
  501.     /* go find the Finder's process information, please */
  502.     if (FindAProcess('FNDR', 'MACS', &process))
  503.         return procNotFound;
  504.  
  505.     myAddressDesc.dataHandle = nil;
  506.     aeDirDesc.dataHandle = nil;
  507.     listElem.dataHandle = nil;
  508.     fileList.dataHandle = nil;
  509.     aeEvent.dataHandle = nil;
  510.  
  511.     /* Create an address descriptor so the AppleEvent manager knows where to send this event */
  512.     if (err = AECreateDesc(typeProcessSerialNumber, (Ptr)&process, sizeof(process), &myAddressDesc))
  513.         goto bail;
  514.  
  515.     /* Create the empty FinderEvent */
  516.     /* it's a Finder 'FNDR', Open Selection 'sope' event */
  517.     if (err = AECreateAppleEvent('FNDR', 'sope', &myAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &aeEvent))
  518.         goto bail;
  519.  
  520.     /* make a FSSpec for the parent folder (see the OpenSelection description in the AE Registry ) */
  521.     /* using the information in the document FSSpec */
  522.     if (err = FSMakeFSSpec(theDocToOpen->vRefNum, theDocToOpen->parID, nil, &dirSpec))
  523.         goto bail;
  524.     if (err = NewAliasMinimal(&dirSpec, &DirAlias))
  525.         goto bail;
  526.  
  527.     /* Create alias for file */
  528.     if (err = NewAliasMinimal(theDocToOpen, &FileAlias))
  529.         goto bail;
  530.  
  531.     /* Create the file  list */
  532.     if (err = AECreateList(nil, 0, false, &fileList))
  533.         goto bail;
  534.  
  535.     /*  create the folder  descriptor */
  536.     HLock((Handle)DirAlias);
  537.         err = AECreateDesc(typeAlias, (void *)*DirAlias, GetHandleSize((Handle)DirAlias), &aeDirDesc);
  538.         if (err) goto bail;
  539.     DisposeHandle((Handle)DirAlias);
  540.     DirAlias = nil;
  541.  
  542.     /* put the Directory Desc in the event as the direct object */
  543.     if ((err = AEPutParamDesc(&aeEvent, keyDirectObject, &aeDirDesc)) == noErr) {
  544.         AEDisposeDesc(&aeDirDesc);
  545.         aeDirDesc.dataHandle = nil;
  546.  
  547.         /*  create the file descriptor and add to aliasList */
  548.         HLock((Handle)FileAlias);
  549.             err = AECreateDesc(typeAlias, (void *)*FileAlias, GetHandleSize((Handle)FileAlias), &listElem);
  550.             if (err) goto bail;
  551.         DisposeHandle((Handle)FileAlias);
  552.         FileAlias = nil;
  553.  
  554.         err = AEPutDesc(&fileList, 0, &listElem);
  555.         if (err) goto bail;
  556.     }
  557.  
  558.     AEDisposeDesc(&listElem);
  559.     listElem.dataHandle = nil;
  560.  
  561.     /* Add the file alias list to the event */
  562.     if (err = AEPutParamDesc(&aeEvent, 'fsel', &fileList))
  563.         goto bail;
  564.  
  565.     AEDisposeDesc(&fileList);
  566.     fileList.dataHandle = nil;
  567.  
  568.     /* And now send the event! */
  569.     err = AESend(&aeEvent, nil, kAENoReply | kAENeverInteract | kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil);
  570.     if (err == noPortErr) {
  571.         err = AESend(&aeEvent, nil, kAENoReply | kAENeverInteract | kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil);
  572.     }
  573.  
  574. bail:
  575.     AEDisposeDesc(&aeEvent);
  576.     AEDisposeDesc(&myAddressDesc);
  577.     AEDisposeDesc(&aeDirDesc);
  578.     AEDisposeDesc(&listElem);
  579.     AEDisposeDesc(&fileList);
  580.     AEDisposeDesc(&aeEvent);
  581.     DisposeHandle((Handle)DirAlias);
  582.     DisposeHandle((Handle)FileAlias);
  583.  
  584.     return err;
  585. }
  586.  
  587.  
  588. OSErr FindAProcess(OSType typeToFind, OSType creatorToFind, ProcessSerialNumberPtr processSN)
  589. {
  590.     OSErr err;
  591.     ProcessInfoRec tempInfo;
  592.  
  593.     processSN->lowLongOfPSN = kNoProcess;
  594.     processSN->highLongOfPSN = kNoProcess;
  595.  
  596.     tempInfo.processInfoLength = sizeof(ProcessInfoRec);
  597.     tempInfo.processName = nil;
  598.     tempInfo.processAppSpec = nil;
  599.  
  600.     do {
  601.         if (err = GetNextProcess(processSN))
  602.             break;
  603.  
  604.         GetProcessInformation(processSN, &tempInfo);
  605.     }  while ((tempInfo.processSignature != creatorToFind) && (tempInfo.processType != typeToFind));
  606.  
  607.     return err;
  608. }
  609.